#include <mc/blockImp.h>
#include <mc/block.h>

namespace mc
{

//! @brief 绘制
void BlockImp::drawInstantiation(opengl::VertexArray& vao, opengl::Texture* texture, unsigned int count, uint64_t size)
{
    vao.bind();
    Block::shader.setInt("tex", texture->index());
    glDrawArraysInstanced(GL_TRIANGLES, 0, count, size);
}

//! @brief 更新实例化矩阵
void BlockImp::updatePositions(opengl::VertexArray& vao, opengl::VertexBuffer& vbo, std::vector<glm::mat4>& instanceMatrices)
{
    vao.bind();

    vbo.bind();
    vbo.setBufferData(instanceMatrices.size() * sizeof(glm::mat4), instanceMatrices.data(), GL_STATIC_DRAW);

    vao.setVertexAttribPointer(2, 4, GL_FLOAT, sizeof(glm::mat4), (void*)0);
    vao.setVertexAttribPointer(3, 4, GL_FLOAT, sizeof(glm::mat4), (void*)(sizeof(glm::vec4)));
    vao.setVertexAttribPointer(4, 4, GL_FLOAT, sizeof(glm::mat4), (void*)(2 * sizeof(glm::vec4)));
    vao.setVertexAttribPointer(5, 4, GL_FLOAT, sizeof(glm::mat4), (void*)(3 * sizeof(glm::vec4)));

    vao.setVertexAttribDivisor(2, 1);
    vao.setVertexAttribDivisor(3, 1);
    vao.setVertexAttribDivisor(4, 1);
    vao.setVertexAttribDivisor(5, 1);
}

//! @brief 初始化 vao
void BlockImp::initVertexArray(opengl::VertexArray& vao, opengl::VertexBuffer& vbo, uint64_t size, const void *data)
{
    vao.bind();
    vbo.bind();
    vbo.setBufferData(size, data, GL_STATIC_DRAW);
    vao.setVertexAttribPointer(0, 3, GL_FLOAT, 5 * sizeof(float), (void*)0);
    vao.setVertexAttribPointer(1, 2, GL_FLOAT, 5 * sizeof(float), (void*)(3 * sizeof(float)));
}

//! @brief 加载方块纹理对象
opengl::Texture* BlockImp::loadTexture(const std::string& texPath)
{
    return opengl::Texture::load2DTexture(texPath, true, GL_REPEAT, GL_REPEAT, GL_NEAREST, GL_NEAREST);
}

}